# -*- coding: utf-8 -*-
# @Date   : 2020/2/25
# @File   : TX_LastIncomeHalfYearAmt_ZBC.py
# @Author : zhaochen

'''eof
name:上半年销售收入
code:TX_LastIncomeHalfYearAmt_ZBC
tableName:
columnName:
groups:
dependencies:TX_CQ_DSJ
type:常用指标
datasourceType:在线指标
description:
eof'''

import sys
import re
import datetime
import pandas as pd
import math

reload(sys)
sys.setdefaultencoding('utf-8')

null_type_list = ['', ' ', None, 'null', 'Null', 'NULL', '/', '-', '--']


def getTable(tableName):
    '''
    获取表
    :param x:
    :return:
    '''
    try:
        data = TX_CQ_DSJ['data'].get(tableName)
        if data in null_type_list:
            return None
        else:
            return data if isinstance(data, list) and len(data) > 0 else [{}]
    except:
        return None


def isFloat(x):
    '''
    判断x为float类型
    :param x:
    :return:
    '''
    try:
        if isinstance(float(x), float):
            if str(x) in ['inf', 'infinity', 'INF', 'INFINITY', 'True', 'NAN', 'nan',
                          'False', '-inf', '-INF', '-INFINITY', '-infinity', 'NaN', 'Nan']:
                return False
            else:
                return True
        else:
            return False
    except:
        return False


def formatDate(time):
    try:
        import re
        import datetime
        r1 = re.compile(u'年|月|日')
        time = r1.sub('.', time)
        try:
            date = datetime.datetime.strptime(time, '%Y.%m.%d')
        except:
            try:
                date = datetime.datetime.strptime(time, '%Y-%m-%d')
            except:
                try:
                    date = datetime.datetime.strptime(time, '%Y/%m/%d')
                except:
                    try:
                        r = re.compile(r'\D+')
                        tmp = r.sub('', time)
                        if len(tmp) > 8:
                            tmp = tmp[:8]
                        date = datetime.datetime.strptime(tmp, '%Y%m%d')
                    except:
                        date = None
        return date
    except:
        return None


def convertDataType(data_value, data_type):
    """
    数据格式转换
    :param data_value:
    :param data_type: float/int/str/date_time
    :return:
    """
    data_value = str(data_value)
    return_data = None
    # float
    if data_type == 'float':
        try:
            return_data = float(data_value) if len(data_value) >= 0 else None
        except:
            return_data = None
    # int
    elif data_type == 'int':
        try:
            return_data = int(data_value) if len(data_value) >= 0 else None
        except:
            return_data = None
    # str
    elif data_type == 'str':
        try:
            return_data = str(data_value) if len(data_value) >= 0 else None
        except:
            return_data = None
    # date_time
    elif data_type == 'date_time':
        r = re.compile(r'\D+')
        try:
            return_data = datetime.datetime.strptime(data_value, '%Y.%m.%d').strftime('%Y-%m-%d')
        except:
            try:
                return_data = datetime.datetime.strptime(data_value, '%Y-%m-%d').strftime('%Y-%m-%d')
            except:
                try:
                    return_data = datetime.datetime.strptime(data_value, '%Y/%m/%d').strftime('%Y-%m-%d')
                except:
                    try:
                        data_value = r.sub('', data_value)
                        return_data = datetime.datetime.strptime(data_value, '%Y%m%d').strftime('%Y-%m-%d')
                    except:
                        return_data = None

    return return_data

def dataPre(dataList=None, key=None):
    """
    对list里面的列表去重月份不标准的
    :param dataList:
    :param key:
    :return:
    """
    dataListTemp = dataList
    data = []
    for i in range(len(dataListTemp)):
        temp = dataListTemp[i].get(key)
        try:
            int(temp)
            data.append(dataListTemp[i])
        except:
            pass
    if len(data) == 0:
        data = [{}]
    return data

def incomePriorityCondition(syptZzsxgm, syptZzsybnsr, putBackYear=2, CcrDate=None):
    """
    优先判断条件：计算近两年销售收入， 优先取一般纳税人
    :param syptZzsxgm: 小规模
    :param syptZzsybnsr: 一般纳税人
    :param putBackYear:
    :param CcrDate:
    :return:
    """
    # 字典排序
    syptZzsxgm = dataPre(syptZzsxgm, key='YF')
    syptZzsybnsr = dataPre(syptZzsybnsr, key='YF')

    # 生成时间轴
    dateIndexList = []
    if CcrDate is None:
        CcrYearMonth = datetime.datetime.now().strftime('%Y-%m-%d')[:7]
        CcrDate = CcrYearMonth + '-01'
        StartDateTmp = str(datetime.datetime.now().year - putBackYear) + CcrDate[4:]
        StartDate = StartDateTmp[:7] + '-01'
    else:
        CcrYear = datetime.datetime.strptime(convertDataType(CcrDate, 'date_time'), '%Y-%m-%d').date().year
        CcrDate = convertDataType(CcrDate, 'date_time')[:7] + '-01'
        StartDate = str(CcrYear - putBackYear) + convertDataType(CcrDate, 'date_time')[4:]

    dateSet = pd.date_range(StartDate, CcrDate, freq='M')

    for i in dateSet:
        year = i.date().year
        month = i.date().month
        dateIndexList.append(str(year) + str(month))
    # 用于保存 按月求和的销售收入
    incomeData = pd.Series(None, index=dateIndexList)

    if syptZzsxgm == [{}] and syptZzsybnsr == [{}]:
        return incomeData
    else:
        # 一般纳税人
        if syptZzsybnsr != [{}]:
            syptZzsybnsr = sorted(syptZzsybnsr, key=lambda x: int(x['YF']))
            for i in range(len(syptZzsybnsr)):
                ND = convertDataType(syptZzsybnsr[i].get('ND'), 'int')
                YF = convertDataType(syptZzsybnsr[i].get('YF'), 'int')
                if ND and YF:
                    NDYF = str(ND) + str(YF)
                    if NDYF in incomeData.index:
                        # 计算一般纳税人的销售收入
                        ASYSLJSDNSJCYBJSE = convertDataType(syptZzsybnsr[i].get('ASYSLJSDNSJCYBJSE'), 'float')
                        AJYZSBFZSHWXSE = convertDataType(syptZzsybnsr[i].get('AJYZSBFZSHWXSE'), 'float')
                        MDTBFCKHWXSE = convertDataType(syptZzsybnsr[i].get('MDTBFCKHWXSE'), 'float')
                        MSHWJLWXSE = convertDataType(syptZzsybnsr[i].get('MSHWJLWXSE'), 'float')
                        if ASYSLJSDNSJCYBJSE is None and AJYZSBFZSHWXSE is None and MDTBFCKHWXSE is None \
                            and MSHWJLWXSE is None:
                            income = None
                        else:
                            ASYSLJSDNSJCYBJSE = ASYSLJSDNSJCYBJSE if ASYSLJSDNSJCYBJSE is not None else 0
                            AJYZSBFZSHWXSE = AJYZSBFZSHWXSE if AJYZSBFZSHWXSE is not None else 0
                            MDTBFCKHWXSE = MDTBFCKHWXSE if MDTBFCKHWXSE is not None else 0
                            MSHWJLWXSE = MSHWJLWXSE if MSHWJLWXSE is not None else 0

                            income = ASYSLJSDNSJCYBJSE + AJYZSBFZSHWXSE + MDTBFCKHWXSE + MSHWJLWXSE

                        if income:
                            if math.isnan(incomeData.loc[NDYF]):
                                incomeData.loc[NDYF] = income
                    else:
                        pass
                else:
                    pass

        # 小规模纳税人
        if syptZzsxgm != [{}]:
            syptZzsxgm = sorted(syptZzsxgm, key=lambda x: int(x['YF']))
            for i in range(len(syptZzsxgm)):
                ND = convertDataType(syptZzsxgm[i].get('ND'), 'int')
                YF = convertDataType(syptZzsxgm[i].get('YF'), 'int')
                if ND and YF:
                    NDYF = str(ND) + str(YF)
                    if NDYF in incomeData.index:
                        YZZZSHWJLWBHSXSEBNBQ = convertDataType(syptZzsxgm[i].get('YZZZSHWJLWBHSXSEBNBQ'), 'float')
                        XSCZBDCBHSXSE = convertDataType(syptZzsxgm[i].get('XSCZBDCBHSXSE'), 'float')
                        MSHWJLWXSEBNBQ = convertDataType(syptZzsxgm[i].get('MSHWJLWXSEBNBQ'), 'float')
                        CKMSHWXSEBNBQ = convertDataType(syptZzsxgm[i].get('CKMSHWXSEBNBQ'), 'float')

                        if YZZZSHWJLWBHSXSEBNBQ is None and XSCZBDCBHSXSE is None and MSHWJLWXSEBNBQ is None \
                            and CKMSHWXSEBNBQ is None:
                            income = None
                        else:
                            YZZZSHWJLWBHSXSEBNBQ = YZZZSHWJLWBHSXSEBNBQ if YZZZSHWJLWBHSXSEBNBQ is not None else 0
                            XSCZBDCBHSXSE = XSCZBDCBHSXSE if XSCZBDCBHSXSE is not None else 0
                            MSHWJLWXSEBNBQ = MSHWJLWXSEBNBQ if MSHWJLWXSEBNBQ is not None else 0
                            CKMSHWXSEBNBQ = CKMSHWXSEBNBQ if CKMSHWXSEBNBQ is not None else 0

                            income = YZZZSHWJLWBHSXSEBNBQ + XSCZBDCBHSXSE + MSHWJLWXSEBNBQ + CKMSHWXSEBNBQ

                        if income:
                            if YF not in [3, 6, 9, 12]:
                                if math.isnan(incomeData.loc[str(ND) + str(YF)]):
                                    incomeData.loc[str(ND) + str(YF)] = income
                            else:
                                # 倒推三个月在时间轴内
                                if str(ND) + str(YF) in incomeData.index and str(ND) + str(YF - 1) in incomeData.index and \
                                                        str(ND) + str(YF - 2) in incomeData.index:

                                    # 临近三个月全为空，3个为空
                                    if math.isnan(incomeData.loc[str(ND) + str(YF)]) \
                                            and math.isnan(incomeData.loc[str(ND) + str(YF - 1)]) \
                                            and math.isnan(incomeData.loc[str(ND) + str(YF - 2)]):
                                        incomeData.loc[str(ND) + str(YF)] = income / 3
                                        incomeData.loc[str(ND) + str(YF - 1)] = income / 3
                                        incomeData.loc[str(ND) + str(YF - 2)] = income / 3
                                    # 临近三个月倒数第3个月非空，2个为空
                                    elif math.isnan(incomeData.loc[str(ND) + str(YF - 1)]) and \
                                            not math.isnan(incomeData.loc[str(ND) + str(YF - 2)]):
                                        incomeData.loc[str(ND) + str(YF - 1)] = income / 2
                                        incomeData.loc[str(ND) + str(YF)] = income / 2
                                    # 临近三个月倒数第2个月非空，2个为空
                                    elif math.isnan(incomeData.loc[str(ND) + str(YF - 2)]) and \
                                            not math.isnan(incomeData.loc[str(ND) + str(YF - 1)]):
                                        incomeData.loc[str(ND) + str(YF - 2)] = income / 2
                                        incomeData.loc[str(ND) + str(YF)] = income / 2
                                    # 临近三个月倒数第三个月非空，1个为空
                                    elif not math.isnan(incomeData.loc[str(ND) + str(YF - 2)]) and \
                                            not math.isnan(incomeData.loc[str(ND) + str(YF - 1)]) \
                                            and math.isnan(incomeData.loc[str(ND) + str(YF)]):
                                        incomeData.loc[str(ND) + str(YF)] = income
                                # 倒数最后YF-2月不在时间轴内
                                elif str(ND) + str(YF - 2) not in incomeData.index and \
                                                        str(ND) + str(YF - 1) in incomeData.index and \
                                                        str(ND) + str(YF) in incomeData.index:
                                    # 倒推两个月都为空
                                    if math.isnan(incomeData.loc[str(ND) + str(YF)]) and math.isnan(
                                            incomeData.loc[str(ND) + str(YF - 1)]):
                                        incomeData.loc[str(ND) + str(YF)] = income / 3
                                        incomeData.loc[str(ND) + str(YF - 1)] = income / 3
                                    elif not math.isnan(incomeData.loc[str(ND) + str(YF - 1)]):
                                        incomeData.loc[str(ND) + str(YF)] = income / 2
                                # 倒数YF-1月不在时间轴内
                                elif str(ND) + str(YF - 1) not in incomeData.index and \
                                                        str(ND) + str(YF - 2) not in incomeData.index and \
                                                        str(ND) + str(YF) in incomeData.index:
                                    if math.isnan(incomeData.loc[str(ND) + str(YF)]):
                                        incomeData.loc[str(ND) + str(YF)] = income / 3
                        else:
                            pass
                    else:
                        pass
                else:
                    pass

    return incomeData



def TX_LastIncomeHalfYearAmt_ZBC():
    try:
        syptZzsxgm = getTable("syptZzsxgm")
        syptZzsybnsr = getTable("syptZzsybnsr")
        if syptZzsxgm is None and syptZzsybnsr is None:
            return u'缺失值'
        else:
            incomeDataSeries = incomePriorityCondition(syptZzsxgm=syptZzsxgm, syptZzsybnsr=syptZzsybnsr, CcrDate=None)
            incomeDataSeries = incomeDataSeries.fillna(value=0)
            return sum(incomeDataSeries[-6:])
    except:
        return u'缺失值'

result = TX_LastIncomeHalfYearAmt_ZBC()